package com.njh.charges.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.hos.entity.his.CareOrderItem;
import com.hos.entity.his.OrderCharge;
import com.hos.entity.his.OrderChargeItem;
import com.hos.entity.sys.User;
import com.hos.utils.IdGeneratorUtil;
import com.hos.utils.WebUtil;
import com.hos.vo.Result;
import com.njh.charges.config.AlipayConfig;
import com.njh.charges.config.TtlQueueConfig;
import com.njh.charges.feigns.UserFeign;
import com.njh.charges.mapper.CareOrderItemMapper;
import com.njh.charges.mapper.CareOrderVoMapper;
import com.njh.charges.mapper.OrderChargeItemMapper;
import com.njh.charges.mapper.OrderChargeMapper;
import com.njh.charges.service.PayService;
import com.njh.charges.vo.AliPay;
import com.njh.charges.vo.AliPaySync;
import com.njh.charges.vo.AlipayBean;
import com.njh.charges.vo.OrderChargeDtoVo;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

@Service
public class PayServiceImpl implements PayService {
    @Resource
    private OrderChargeMapper orderChargeMapper;
    @Resource
    private OrderChargeItemMapper orderChargeItemMapper;
    @Resource
    private UserFeign userFeign;
    @Resource
    private CareOrderItemMapper careOrderItemMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private AlipayConfig alipayConfig;
    @Resource
    private RabbitTemplate rabbitTemplate;


    @Override
    public Object pay(OrderChargeDtoVo orderChargeDtoVo) {


        //新建his_order_charge（订单）    ch_id,reg_id不变  自创order_id
        //新建his_order_charge_item(订单详情)     co_id直接拿    order_id如上    自创item_id（每个都不一样）


        String OrderId=IdGeneratorUtil.nextId("ODC");
        Double sum=0D;

        for (OrderChargeItem c :
                orderChargeDtoVo.getOrderChargeItemDtoList()) {

            sum+=c.getItemAmount().doubleValue();

            //根据itemid查询OrderChargeItem表，如果存在则修改现有的表，没有则新增
            QueryWrapper<OrderChargeItem> queryWrapper=new QueryWrapper();
            queryWrapper.lambda()
                            .eq(OrderChargeItem::getItemId,c.getItemId());
            OrderChargeItem orderChargeItem1 = orderChargeItemMapper.selectOne(queryWrapper);
            if(orderChargeItem1==null){
                //新建his_order_charge_item(订单详情)     co_id直接拿    order_id如上    自创item_id（每个都不一样）
                OrderChargeItem orderChargeItem=new OrderChargeItem();
                orderChargeItem.setItemId(c.getItemId());
                orderChargeItem.setCoId(c.getCoId());
                orderChargeItem.setItemName(c.getItemName());
                orderChargeItem.setItemPrice(c.getItemPrice());
                orderChargeItem.setItemNum(c.getItemNum());
                orderChargeItem.setItemAmount(c.getItemAmount());
                orderChargeItem.setOrderId(OrderId);
                orderChargeItem.setItemType(c.getItemType());
                orderChargeItem.setStatus("0");
                orderChargeItemMapper.insert(orderChargeItem);
            }else{
                //存在订单则修改旧订单信息
                //修改his_order_charge_item(订单详情) 的订单号orderid
                UpdateWrapper<OrderChargeItem> wrapper=new UpdateWrapper();
                wrapper.lambda()
                        .set(OrderChargeItem::getOrderId,OrderId)
                        .eq(OrderChargeItem::getItemId,c.getItemId());
                orderChargeItemMapper.update(wrapper);
            }
        }

        //新建his_order_charge（订单）    ch_id,reg_id不变  自创order_id
        OrderCharge orderCharge=new OrderCharge();
        orderCharge.setOrderId(OrderId);
        orderCharge.setOrderAmount(BigDecimal.valueOf(sum));
        orderCharge.setChId(orderChargeDtoVo.getOrderChargeDto().getChId());
        orderCharge.setRegId(orderChargeDtoVo.getOrderChargeDto().getRegId());
        orderCharge.setPatientName(orderChargeDtoVo.getOrderChargeDto().getPatientName());
        orderCharge.setOrderStatus("0");
        orderCharge.setPayPlatformId(null);
        orderCharge.setPayTime(null);
        orderCharge.setPayType("1");
        orderCharge.setCreateTime(new Date());
        orderCharge.setUpdateTime(null);
        orderCharge.setCreateBy(getUserByToken().getUserName());
        orderCharge.setUpdateBy(null);
        orderChargeMapper.insert(orderCharge);


        // 存入消息队列中
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setMessageId(OrderId);
        Message message = new Message(OrderId.getBytes(), messageProperties);
        rabbitTemplate.convertAndSend(TtlQueueConfig.ORDER_EXCHANGE, "", message);


        //创建支付宝支付二维码
        AliPay aliPay = new AliPay();
        //设置alipay数据
        aliPay.setTraceNo(OrderId);
        BigDecimal orderAmount = BigDecimal.valueOf(sum);
        aliPay.setTotalAmount(sum);
        aliPay.setSubject(orderChargeDtoVo.getOrderChargeDto().getPatientName()+"的病例订单");

        // 1. 创建Client，通用SDK提供的Client，负责调用支付宝的API
        String format = "json";
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getGatewayUrl(), alipayConfig.getAppId(),
                alipayConfig.getPrivateKey(), format, alipayConfig.getCharset(), alipayConfig.getPublicKey(), alipayConfig.getSignType());

        // 2. 创建 Request并设置Request参数
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();  // 发送请求的 Request类
        request.setNotifyUrl(alipayConfig.getNotifyUrl());
        request.setBizContent("{" +
                "\"out_trade_no\":\""+aliPay.getTraceNo()+"\"," + // 商户订单号
                "\"total_amount\":\""+ aliPay.getTotalAmount() +"\"," +    // 商品价格
                "\"subject\":\"支付宝支付\"," +    // 商品标题
                "\"store_id\":\"医院预约挂号系统\"," +    // 组织或公司名
                "\"timeout_express\":\"20m\"}");    // 订单有效时间
        try {
            AlipayTradePrecreateResponse response = alipayClient.execute(request);
            String qrCode = response.getQrCode();
            Map<String,Object> payObj = new HashMap<>();
            payObj.put("payUrl",qrCode);
            payObj.put("payId",aliPay.getTraceNo());
            payObj.put("orderId",OrderId);
            payObj.put("allAmount",aliPay.getTotalAmount());
            return payObj;
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }




    }

        @Override
        public Result AlipayTrade(String orderId) {





            String format = "json";
            AlipayClient client = new DefaultAlipayClient(alipayConfig.getGatewayUrl(),alipayConfig.getAppId(),
                    alipayConfig.getPrivateKey(),format,alipayConfig.getCharset(), alipayConfig.getPublicKey(),alipayConfig.getSignType());
            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no",orderId);
            request.setBizContent(bizContent.toString());
            try {

                AlipayTradeQueryResponse response = client.execute(request);
                String tradeNo = response.getTradeNo();



                if (StringUtils.hasText(response.getTradeStatus())){
                    switch (response.getTradeStatus()){
                        case "WAIT_BUYER_PAY":
                            return new Result(203,"等待付款",null);
                        case "TRADE_CLOSED":
                            return new Result(204,"未付款",null);
                        case "TRADE_SUCCESS":

                            //根据item_id修改his_care_order_item的status
                            //修改his_order_charge（订单）    修改status 添加支付信息
                            //修改his_order_charge_item(订单详情)    修改status

                            //根据orderid查询订单的所有子项
                            QueryWrapper<OrderChargeItem> queryWrapper=new QueryWrapper<>();
                            queryWrapper.lambda()
                                    .eq(OrderChargeItem::getOrderId,orderId);
                            List<OrderChargeItem> orderChargeItems = orderChargeItemMapper.selectList(queryWrapper);

                            for (OrderChargeItem c :
                                    orderChargeItems) {

                                //根据item_id修改his_care_order_item的status
                                UpdateWrapper<CareOrderItem> wrapper=new UpdateWrapper();
                                wrapper.lambda()
                                        .set(CareOrderItem::getStatus,1)
                                        .eq(CareOrderItem::getItemId,c.getItemId());
                                careOrderItemMapper.update(wrapper);

                                //修改his_order_charge_item(订单详情)    修改status
                                UpdateWrapper<OrderChargeItem> wrapper2=new UpdateWrapper();
                                wrapper2.lambda()
                                        .set(OrderChargeItem::getStatus,1)
                                        .eq(OrderChargeItem::getItemId,c.getItemId());
                                orderChargeItemMapper.update(wrapper2);
                            }

                            //修改his_order_charge（订单）    修改status 添加支付信息
                            UpdateWrapper<OrderCharge> wrapper3=new UpdateWrapper();
                            wrapper3.lambda()
                                    .set(OrderCharge::getOrderStatus,1)
                                    .set(OrderCharge::getPayPlatformId,tradeNo)
                                    .set(OrderCharge::getPayTime,new Date())
                                    .set(OrderCharge::getUpdateTime,new Date())
                                    .set(OrderCharge::getUpdateBy,getUserByToken().getUserName())
                                    .eq(OrderCharge::getOrderId,orderId);
                            orderChargeMapper.update(wrapper3);
                            return new Result(200,"支付成功",1);
                        default:
                            return new Result(500,"交易结束",null);
                    }
                }
            } catch (AlipayApiException e) {
                return new Result(205,"查询失败",null);
            }
            return new Result(203,"等待付款",null);
        }

    @Override
    public Object toPayOrderWithZfb(String OrderId) {

        //查询已有的订单信息
        QueryWrapper<OrderCharge> wrapper=new QueryWrapper<>();
        wrapper.lambda()
                .eq(OrderCharge::getOrderId,OrderId);
        OrderCharge orderCharge = orderChargeMapper.selectOne(wrapper);

        //查询已有的订单子表信息
        //如果子表为空，则删除订单表
        QueryWrapper<OrderChargeItem> wrapper2=new QueryWrapper<>();
        wrapper2.lambda()
                .eq(OrderChargeItem::getOrderId,OrderId);
        List<OrderChargeItem> orderChargeItems = orderChargeItemMapper.selectList(wrapper2);
        System.out.println(orderChargeItems);
        System.out.println(orderChargeItems.size()>0);
        if(orderChargeItems.size()==0){
            orderChargeMapper.deleteById(OrderId);

            Map<String,Object> payObj = new HashMap<>();
            payObj.put("payUrl",null);
            payObj.put("payId",null);
            payObj.put("orderId",null);
            payObj.put("allAmount",null);
            return payObj;
        }

        //创建支付宝支付二维码
        AliPay aliPay = new AliPay();
        //设置alipay数据
        aliPay.setTraceNo(OrderId);
        BigDecimal orderAmount = orderCharge.getOrderAmount();
        aliPay.setTotalAmount(orderAmount.doubleValue());
        aliPay.setSubject(orderCharge.getPatientName()+"的病例订单");

        // 1. 创建Client，通用SDK提供的Client，负责调用支付宝的API
        String format = "json";
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getGatewayUrl(), alipayConfig.getAppId(),
                alipayConfig.getPrivateKey(), format, alipayConfig.getCharset(), alipayConfig.getPublicKey(), alipayConfig.getSignType());

        // 2. 创建 Request并设置Request参数
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();  // 发送请求的 Request类
        request.setNotifyUrl(alipayConfig.getNotifyUrl());
        request.setBizContent("{" +
                "\"out_trade_no\":\""+aliPay.getTraceNo()+"\"," + // 商户订单号
                "\"total_amount\":\""+ aliPay.getTotalAmount() +"\"," +    // 商品价格
                "\"subject\":\"支付宝支付\"," +    // 商品标题
                "\"store_id\":\"医院预约挂号系统\"," +    // 组织或公司名
                "\"timeout_express\":\"20m\"}");    // 订单有效时间
        try {
            AlipayTradePrecreateResponse response = alipayClient.execute(request);
            String qrCode = response.getQrCode();
            Map<String,Object> payObj = new HashMap<>();
            payObj.put("payUrl",qrCode);
            payObj.put("payId",aliPay.getTraceNo());
            payObj.put("orderId",OrderId);
            payObj.put("allAmount",aliPay.getTotalAmount());
            return payObj;
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * @return com.hos.entity.sys.User
     * @create by: 陈海彬
     * @description: 获取请求用户的信息
     * @create time: 2023/12/12 10:39
     */
    private User getUserByToken() {
        String token = WebUtil.getToken();
        String phone = redisTemplate.opsForValue().get("user:" + token);
        return userFeign.selectUserByPhone(phone);
    }


}